/* Author:  Seth M. Cook
 * Date of Revision: 10/6/2011
 * Program: Purdue First Login System
 * Purpose:  To log a person into their office hours when they login to their computer account
 * Implementation: To be inserted into the startup folder
 */

import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;

public class Main {

	//Date Formats
	public static final String DATE_FORMAT = "yyyy-MM-dd hh:mma";
	public static final String DATE_FILE_OUTPUT = "EEEE,dd/MM/yyyy,hh:mma";
	public static final String DATE_WEEK_DAY = "EEEE";
	public static final String DATE_TIME = "hh:mma";
	public static final String DATE_LOG_TIME = "MM/dd/yyyy HH:mm:ss";
	
	//File Locations
	public static final String FILE_DIRECTORY = "P:\\OfficeHours\\";
	public static final String FILE_LOGIN   = FILE_DIRECTORY+"login.csv";
	public static final String FILE_OFFICE_TIMES = FILE_DIRECTORY+"officeHours.csv";
	public static final String FILE_PROGRAM_LOG = FILE_DIRECTORY+"programLog.txt";
	
	//Image Locations
	public static final String IMAGE_ICON = "PFPIcon.png";
	public static final String IMAGE_ICON_SMALL = "PFPIcon16X16.png";
	public static final String IMAGE_LOGGEDIN_ICON = "PFPLoggedInIcon.png";
	public static final String IMAGE_LOGGEDIN_ICON_SMALL = "PFPLoggedInIcon16X16.png";
	
	//Shutdown Commands
	public static final String SHUTDOWN_ABORT = "cmd /c start "+"shutdownAbort.bat";
	public static final String SHUTDOWN_LOGOFF = "cmd /c start "+"logoff.bat";
	
	//Global Variables
	public Calendar cal = Calendar.getInstance();
	public SimpleDateFormat timeFormater;
	public BufferedReader reader;
	public BufferedWriter writer;
	public String username;
	public boolean loggedin;
	public Date timeEntered;
	
	public void logEvent(String event) {
		timeFormater = new SimpleDateFormat(DATE_LOG_TIME);
		String time = timeFormater.format(Calendar.getInstance().getTime());
		
		try {
			writer = new BufferedWriter(new FileWriter(FILE_PROGRAM_LOG,true));
			writer.write(time + "|:: " + event);
			writer.newLine();
			System.out.println(time + "|:: " + event);
			writer.close();
		} catch(IOException e){
			//I need to do something to let ME know that the program isn't working.
			System.out.println(time+ "|:: PROGRAM LOGGING ERROR (I broke :'( ): "+e.getMessage());
		}
	}
	
	public String getUsername() {
		return System.getProperty("user.name");
	}
	
	public void loginFileStore(String currentTime, boolean login) {
		try {
			writer = new BufferedWriter(new FileWriter(FILE_LOGIN,true));
			writer.write(username+","+currentTime);
			if(login)
				writer.write(",arrived");
			else
				writer.write(",left");
			writer.newLine();
			writer.close();
			if(login)
				logEvent(username + " has successfully logged into their office hour.");
			else
				logEvent(username + " has successfully logged out of their office hour.");
		}catch(Exception e) {
			logEvent("Did not write to the file. User- "+username+" Error- " + e.getMessage());
		}
	}
	
	public boolean parseOfficeHourLine(String line){
		String user = line.substring(0,line.indexOf(","));
		line = line.substring(line.indexOf(",")+1);
		
		if(username.equals(user)) {
			logEvent("I found " + username + " in the file!");
			
			String weekDay = line.substring(0,line.indexOf(","));
			line = line.substring(line.indexOf(",")+1);
			
			//gets the current date/time
			cal = Calendar.getInstance();
			
			//Checks user's office hour DAY to the current DAY
			timeFormater = new SimpleDateFormat(DATE_WEEK_DAY);
			if(weekDay.equals(timeFormater.format(cal.getTime()))) {
				
				//Gets the office hour beginning time and ending time
				String enterTime=line.substring(0,line.indexOf(","));
				String outTime=line.substring(line.indexOf(",")+1).trim();
				
				//Gets the current month, day, and year
				String year = new SimpleDateFormat("yyyy").format(cal.getTime());
				String month = new SimpleDateFormat("MM").format(cal.getTime());
				String day = new SimpleDateFormat("dd").format(cal.getTime());
				
				//Assembles their beginning office hour time using the current day, month, and year
				timeFormater = new SimpleDateFormat(DATE_FORMAT);
				Date time = null;
				try{
					time = (Date)timeFormater.parse(year + "-"+month+"-"+day+" "+enterTime);
				}catch(Exception e){}
				Calendar eTime = Calendar.getInstance();
				eTime.setTime(time);
				//allows for a buffer enter time
				eTime.add(Calendar.MINUTE,-20);
				
				//Assembles their ending office hour time using the current day, month, and year
				time = null;
				try{
					time = (Date)timeFormater.parse(year + "-"+month+"-"+day+" "+outTime);
				}catch(Exception e){}
				Calendar oTime = Calendar.getInstance();
				oTime.setTime(time);
				oTime.add(Calendar.MINUTE,-30);
				
				//If the user logged in within the flex time, they are recorded.
				if(eTime.compareTo(cal)<=0 && oTime.compareTo(cal)>=0) {
					timeFormater = new SimpleDateFormat(DATE_FILE_OUTPUT);
					loginFileStore(timeFormater.format(cal.getTime()),true);
					loggedin = true;
					
					logEvent(username + " has shown up to their office hour and is now logged in.");
				}
			}
			return true;
		}
		
		return false;
	}
	
	public boolean isOfficeHour(){
		reader = null;
		try {
			reader = new BufferedReader(new FileReader(FILE_OFFICE_TIMES));
		} catch(Exception e) {
			System.out.println("Fail: "+e.getLocalizedMessage());
			return false;
		}
		
		if(reader!=null){
			String line = null;
			boolean isOfficeHour = false;
			try{
				while((line=reader.readLine())!=null && !isOfficeHour) {
					isOfficeHour = parseOfficeHourLine(line);
				}
				reader.close();
				return isOfficeHour;
			} catch(Exception e){
				logEvent("My apologies, I unsuccessfully read the necissary office hours file. User- "+username+". Error- " + e.getMessage());
			}
			if(!isOfficeHour)
				logEvent("Sorry, but I could not find the user in the office hours file.  Is "+username+" in there?");
		}
		return false;
	}
	
	public String getTime() {
		SimpleDateFormat d = new SimpleDateFormat(DATE_TIME);
		return d.format(cal.getTime());
	}
	
	public boolean waitForFile(){
		File file = new File(FILE_OFFICE_TIMES);
		int count=0;
		while(!file.exists() && count<1200){
			count++;
			try{Thread.sleep(100);}catch(Exception e){logEvent("We're having troubles finding the file. Error: "+e.toString());}
		}
		if(count>=1200)
			return false;
		return true;
	}
	
	public Main() {
		username = getUsername();
		
		if(waitForFile()){
			logEvent(username + " has logged into the computer.");
		
			JFrame f = new JFrame("Office Hours Login");
			f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			
			JLabel lbl = new JLabel();
			Border paddingBorder = BorderFactory.createEmptyBorder(10,30,10,30);
			lbl.setBorder(BorderFactory.createCompoundBorder(null, paddingBorder));
			
			try{
				f.setIconImage(new ImageIcon(Main.class.getResource(IMAGE_ICON)).getImage());
			}catch(Exception e){
				logEvent("I could not load icon image. Error- "+e.getMessage());
			}
			
			isOfficeHour();
			if(loggedin) {
				lbl.setText(username.substring(0,1).toUpperCase()+username.substring(1) + ", thank you for attending your office hour.  We have logged you in.");
				f.add(lbl);
				f.pack();
				f.setVisible(true);
			}
			
			String image = "";
			if(loggedin)
				image=IMAGE_LOGGEDIN_ICON_SMALL;
			else
				image=IMAGE_ICON_SMALL;
			
			TrayIcon tray = null;
			try {
				tray = new TrayIcon(new ImageIcon(Main.class.getResource(image)).getImage());
			} catch(Exception e){
				tray = new TrayIcon(Toolkit.getDefaultToolkit().getImage(image));
			}
			tray.setToolTip("PFP Office Hour System");
			tray.setImageAutoSize(true);
			
			PopupMenu mnuMain = new PopupMenu();
			
			MenuItem mnuExit = new MenuItem("Exit");
			mnuExit.addActionListener(new ActionListener(){	public void actionPerformed(ActionEvent e){	System.exit(0); }});
			
			mnuMain.add(mnuExit);
			tray.setPopupMenu(mnuMain);
			try{SystemTray.getSystemTray().add(tray);}catch(Exception e){}
			
		} else {
			logEvent("Crap");
		}
	}
	
	public static void main(String[]args) {
		Main m = new Main();
	}

}//End of Class
